library(tidyverse)
library(ggtext)
library(cowplot)
patients <- readxl::read_xlsx("2._byetta_insulin_music_diagram_v5 (30) (12).xlsx")
patients %>%
head()
patients <- patients %>%
pivot_longer(-`Patient ID`, names_to = "date", values_to = "med") %>%
rename(id = `Patient ID`)
patients
patients %>%
# filter(id == 1) %>%
mutate(date = as.Date(as.numeric(date),
origin = '1899-12-30')) %>%
group_by(id, date) %>%
arrange(id, date) %>%
mutate(bought_ins = ifelse("In" %in% med, 1, 0),
bought_by = ifelse("By" %in% med, 1, 0)) %>%
filter(row_number() == 1) %>%
select(-med) %>%
ungroup() %>%
group_by(id) %>%
mutate(used_ins = ifelse(bought_ins == 0 &
((lag(bought_ins, default = 0, n = 1) == 1) |
(lag(bought_ins, default = 0, n = 2) == 1) |
(lag(bought_ins, default = 0, n = 3) == 1) |
(lag(bought_ins, default = 0, n = 4) == 1) |
(lag(bought_ins, default = 0, n = 5) == 1) |
(lag(bought_ins, default = 0, n = 6) == 1)),
1, bought_ins),
used_by = ifelse(bought_by == 0 &
((lag(bought_by, default = 0, n = 1) == 1) |
(lag(bought_by, default = 0, n = 2) == 1)),
1, bought_by),
n_med = used_ins + used_by) %>%
mutate(comed = ifelse(used_ins == 1 & used_by == 1, 1, 0),
comed_rate = round(sum(comed) / n() * 100,1)) %>%
summarise(comed_rate = round(sum(comed) / n() * 100,1)) %>%
arrange(-comed_rate)
comed <- patients %>%
# filter(id == 1) %>%
mutate(date = as.Date(as.numeric(date),
origin = '1899-12-30')) %>%
group_by(id, date) %>%
arrange(id, date) %>%
mutate(bought_ins = ifelse("In" %in% med, 1, 0),
bought_by = ifelse("By" %in% med, 1, 0)) %>%
filter(row_number() == 1) %>%
select(-med) %>%
ungroup() %>%
group_by(id) %>%
mutate(used_ins = ifelse(bought_ins == 0 &
((lag(bought_ins, default = 0, n = 1) == 1) |
(lag(bought_ins, default = 0, n = 2) == 1) |
(lag(bought_ins, default = 0, n = 3) == 1) |
(lag(bought_ins, default = 0, n = 4) == 1) |
(lag(bought_ins, default = 0, n = 5) == 1) |
(lag(bought_ins, default = 0, n = 6) == 1)),
1, bought_ins),
used_by = ifelse(bought_by == 0 &
((lag(bought_by, default = 0, n = 1) == 1) |
(lag(bought_by, default = 0, n = 2) == 1)),
1, bought_by),
n_med = used_ins + used_by) %>%
mutate(comed = ifelse(used_ins == 1 & used_by == 1, 1, 0),
comed_rate = round(sum(comed) / n() * 100,1),
name = paste0("#",id, " (", comed_rate, "%)")) %>%
ungroup()
comed
mycolors <- c("darkgoldenrod3", "coral3")
break.vec <- c(seq(from = as.Date("2012-01-01"), to = as.Date("2014-03-01"),
by = "6 months"))
ggplot(comed, aes(x=date, )) +
geom_col(aes(y=comed, col = "Both"), fill = "gray40", alpha = 0.3, width = 14, show.legend = F) +
geom_col(aes(y=-comed, col = "Both"), fill = "gray40", alpha = 0.3, width = 14, show.legend = F) +
geom_vline(xintercept = as.numeric(as.Date(c("2012-01-01", "2013-01-01", "2014-01-01"))),
col = "gray20", lwd = 0.3) +
geom_line(aes(y = -used_ins, col="Insulin"), size = 1.2) +
geom_line(aes(y = used_by, col = "Byetta"), size = 1.2) +
geom_point(aes(y = -bought_ins * 2 + 1.8, fill = "Insulin"), col = mycolors[2], size = 0.8) +
geom_point(aes(y = bought_by * 2 - 1.8, fill = "Byetta"), col = mycolors[1], size = 0.8, show.legend = F) +
scale_fill_manual(name = "Bought:",
values = c(1, 1),
breaks = c("Byetta", "Insulin"),
guide = guide_legend(override.aes = list(color = mycolors,
size = 2))) +
scale_color_manual(values = c(mycolors, alpha("white", 0)),
breaks = c("Byetta", "Insulin", "Both"),
guide = guide_legend(override.aes = list(color = c(mycolors, "gray80"),
size = c(2,2,6)))) +
scale_y_continuous(breaks = c(-1,0,1), labels = c("Insulin", "None", "Byetta"), limits = c(-1,1)) +
# scale_x_date(date_labels = "%b %Y", date_breaks = "6 months",
# minor_breaks = "1 month",
# expand = c(0,0),
# limits = c(min=min(date), max = max(date)),
# ) +
scale_x_date(breaks = break.vec,
date_labels = "%b %Y") +
facet_wrap(id ~., labeller = as_labeller(setNames(comed$name, comed$id))) +
labs(col = "Taking:", x = "Date", y = "Medication",
title = "Insulin and Byetta Co-Medication Study",
subtitle = "Patient ID and co-medication rate (%), from January 2012 to February 2014") +
theme_bw() +
theme(axis.text.x = element_text(angle = 90, hjust = 1, vjust = 0.5),
panel.grid.minor.y = element_blank(),
strip.background = element_rect(fill = "gray98"))

comed %>%
mutate(id = fct_reorder(as.factor(id), comed_rate)) %>%
pull(id)
[1] 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
[44] 1 1 1 1 1 1 1 1 1 1 1 1 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2
[87] 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3
[130] 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 4 4 4 4 4 4 4
[173] 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4
[216] 4 4 4 4 4 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5
[259] 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6
[302] 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 7 7 7 7 7 7 7 7 7 7 7 7 7 7
[345] 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 9 9
[388] 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9
[431] 9 9 9 9 9 9 9 9 9 9 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11
[474] 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 13 13 13 13 13 13 13 13 13 13 13 13 13 13 13 13 13 13 13 13 13
[517] 13 13 13 13 13 13 13 13 13 13 13 13 13 13 13 13 13 13 13 13 13 13 13 13 13 13 13 13 13 13 13 13 13 13 14 14 14 14 14 14 14 14 14
[560] 14 14 14 14 14 14 14 14 14 14 14 14 14 14 14 14 14 14 14 14 14 14 14 14 14 14 14 14 14 14 14 14 14 14 14 14 14 14 14 14 14 14 14
[603] 14 14 14 15 15 15 15 15 15 15 15 15 15 15 15 15 15 15 15 15 15 15 15 15 15 15 15 15 15 15 15 15 15 15 15 15 15 15 15 15 15 15 15
[646] 15 15 15 15 15 15 15 15 15 15 15 15 15 15 15 16 16 16 16 16 16 16 16 16 16 16 16 16 16 16 16 16 16 16 16 16 16 16 16 16 16 16 16
[689] 16 16 16 16 16 16 16 16 16 16 16 16 16 16 16 16 16 16 16 16 16 16 16 16 16 16 16 17 17 17 17 17 17 17 17 17 17 17 17 17 17 17 17
[732] 17 17 17 17 17 17 17 17 17 17 17 17 17 17 17 17 17 17 17 17 17 17 17 17 17 17 17 17 17 17 17 17 17 17 17 17 17 17 17 19 19 19 19
[775] 19 19 19 19 19 19 19 19 19 19 19 19 19 19 19 19 19 19 19 19 19 19 19 19 19 19 19 19 19 19 19 19 19 19 19 19 19 19 19 19 19 19 19
[818] 19 19 19 19 19 19 19 19 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20
[861] 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 21 21 21 21 21 21 21 21 21 21 21 21 21 21 21 21 21 21 21 21 21 21 21
[904] 21 21 21 21 21 21 21 21 21 21 21 21 21 21 21 21 21 21 21 21 21 21 21 21 21 21 21 21 21 21 21 21 22 22 22 22 22 22 22 22 22 22 22
[947] 22 22 22 22 22 22 22 22 22 22 22 22 22 22 22 22 22 22 22 22 22 22 22 22 22 22 22 22 22 22 22 22 22 22 22 22 22 22 22 22 22 22 22
[990] 22 23 23 23 23 23 23 23 23 23 23
[ reached getOption("max.print") -- omitted 2740 entries ]
68 Levels: 22 23 68 69 16 17 28 33 3 47 54 73 44 57 64 74 78 26 39 53 14 20 31 32 71 42 29 60 63 35 46 9 48 58 65 30 56 7 1 4 45 ... 41
mycolors <- c("darkgoldenrod3", "coral3")
break.vec <- c(seq(from = as.Date("2012-01-01"), to = as.Date("2014-03-01"),
by = "6 months"))
ggplot(comed %>% mutate(id = fct_reorder(as.factor(id), -comed_rate)), aes(x=date, )) +
geom_col(aes(y=comed, col = "Both"), fill = "gray40", alpha = 0.3, width = 14, show.legend = F) +
geom_col(aes(y=-comed, col = "Both"), fill = "gray40", alpha = 0.3, width = 14, show.legend = F) +
geom_vline(xintercept = as.numeric(as.Date(c("2012-01-01", "2013-01-01", "2014-01-01"))),
col = "gray20", lwd = 0.3) +
geom_line(aes(y = -used_ins, col="Insulin"), size = 1.2) +
geom_line(aes(y = used_by, col = "Byetta"), size = 1.2) +
geom_point(aes(y = -bought_ins * 2 + 1.8, fill = "Insulin"), col = mycolors[2], size = 0.8) +
geom_point(aes(y = bought_by * 2 - 1.8, fill = "Byetta"), col = mycolors[1], size = 0.8, show.legend = F) +
scale_fill_manual(name = "Bought:",
values = c(1, 1),
breaks = c("Byetta", "Insulin"),
guide = guide_legend(override.aes = list(color = mycolors,
size = 2))) +
scale_color_manual(values = c(mycolors, alpha("white", 0)),
breaks = c("Byetta", "Insulin", "Both"),
guide = guide_legend(override.aes = list(color = c(mycolors, "gray80"),
size = c(2,2,6)))) +
scale_y_continuous(breaks = c(-1,0,1), labels = c("Insulin", "None", "Byetta"), limits = c(-1,1)) +
scale_x_date(breaks = break.vec,
date_labels = "%b %Y") +
facet_wrap(id ~., labeller = as_labeller(setNames(comed$name, comed$id))) +
labs(col = "Taking:", x = "Date", y = "Medication",
title = "Insulin and Byetta Co-Medication Study",
subtitle = "Patient ID and co-medication rate (%), from January 2012 to February 2014") +
theme_bw() +
theme(axis.text.x = element_text(angle = 90, hjust = 1, vjust = 0.5),
panel.grid.minor.y = element_blank(),
strip.background = element_rect(fill = "gray98"))

mycolors <- c("darkgoldenrod3", "coral3")
mycolors <- c("#90EF77", "#017182") #9aee84, #073A52
highlight <- "coral3" #"#FC1B51"
break.vec <- c(seq(from = as.Date("2012-01-01"), to = as.Date("2014-03-01"),
by = "6 months"))
pdata <- comed %>% filter(id < 500) %>% mutate(id = fct_reorder(as.factor(id), -comed_rate))
ggplot(pdata, aes(x=date, )) +
geom_col(data = pdata %>% filter(n_med <= 1),
aes(y=n_med, col = "Both"), fill = "gray40", alpha = 0.5, width = 14, show.legend = F) +
# geom_line(aes(y=n_med), col="black", show.legend = F) +
geom_col(data = pdata %>% filter(n_med > 1),
aes(y=n_med, col = "Both"), fill = highlight, alpha = 0.6, width = 14, show.legend = F) +
geom_vline(xintercept = as.numeric(as.Date(c("2012-01-01", "2013-01-01", "2014-01-01"))),
col = "gray20", lwd = 0.3) +
# geom_line(aes(y = -used_ins, col="Insulin"), size = 1.2) +
# geom_line(aes(y = used_by, col = "Byetta"), size = 1.2) +
geom_point(data = pdata %>% filter(used_ins == 1, n_med == 1),
aes(y = 0.1, fill = "Insulin"), col = mycolors[1], size = 0.6) +
geom_point(data = pdata %>% filter(used_by == 1, n_med == 1),
aes(y = 0.1, fill = "Byetta"), col = mycolors[2], size = 0.6) +
geom_point(aes(y = -1, fill = "Both"),) +
# geom_point(aes(y = bought_by * 2 - 1.8, fill = "Byetta"), col = mycolors[1], size = 0.8, show.legend = F) +
scale_fill_manual(name = "Medication:",
values = c(1, 1, 1),
breaks = c("Insulin", "Byetta", "Both"),
guide = guide_legend(override.aes = list(color = c(mycolors, highlight),
shape = c(16,16,15),
alpha = c(1,1,0.4),
size = c(2,2,6)))) +
scale_color_manual(values = c(mycolors, alpha("white", 0)),
breaks = c("Byetta", "Insulin", "Both"),
guide = guide_legend(override.aes = list(color = c(mycolors, "gray80"),
size = c(2,2,6)))) +
scale_y_continuous(breaks = c(0,1,2),
labels = c("0", "1", "2"),
limits = c(0, 2)) +
scale_x_date(breaks = break.vec,
date_labels = "%b %Y") +
facet_wrap(id ~., labeller = as_labeller(setNames(comed$name, comed$id))) +
labs(col = "Taking:", x = "Date", y = "# Taken Medications",
title = "Insulin and Byetta Co-Medication Study",
subtitle = "Patient ID and co-medication rate (%), from January 2012 to February 2014") +
theme_bw() +
theme(axis.text.x = element_text(angle = 90, hjust = 1, vjust = 0.5),
axis.text.y = element_blank(),
axis.ticks.y = element_blank(),
panel.grid.minor.y = element_blank(),
strip.background = element_rect(fill = "gray98"))

pdata <- comed %>% filter(id < 500) %>% mutate(id = fct_reorder(as.factor(id), comed_rate)) %>%
mutate(med = case_when(
n_med == 2 ~ "Both",
n_med == 1 & used_ins == 1 ~ "Insulin",
n_med == 1 & used_by == 1 ~ "Byetta",
TRUE ~ "None"
),
alpha = ifelse(med == "None", 0, 1),
name = paste0("#",id, " **(", comed_rate, "%)**"))
axis_size <- 5.5
p1 <- ggplot(pdata %>% filter(as.numeric(id) > 34), aes(x=date, y=id)) +
geom_tile(aes(fill = factor(med), alpha = alpha), size = 1) +
# geom_point(aes(col = factor(med), alpha = alpha), shape = 15, size = 5) +
# geom_point(data = pdata %>% filter(used_ins == 1, n_med == 1),
# aes(fill = "Insulin"), col = mycolors[1], size = 0.6) +
# geom_point(data = pdata %>% filter(used_by == 1, n_med == 1),
# aes(fill = "Byetta"), col = mycolors[2], size = 0.6) +
scale_y_discrete(breaks = pdata$id,
labels = pdata$name) +
scale_fill_manual(values = c(highlight, mycolors, "white"),
breaks = c("Both", "Insulin", "Byetta", "None"),
guide = guide_legend(override.aes = list(color = c("white", "gray80", highlight),
size = c(2,2,6)))) +
scale_x_date(breaks = break.vec,
date_labels = "%b %Y") +
theme_bw() +
labs(col = "Taking:", x = "Date", y = "Patient ID",
) +
theme(legend.position = "none",
axis.text.y = element_markdown(size=axis_size),
plot.title = element_markdown(lineheight = 1.1),
legend.text = element_markdown(size = 11)
)
p2 <- ggplot(pdata %>% filter(as.numeric(id) <= 34), aes(x=date, y=id)) +
geom_tile(aes(fill = factor(med), alpha = alpha), size = 1) +
scale_y_discrete(breaks = pdata$id,
labels = pdata$name) +
scale_fill_manual(values = c(highlight, mycolors, "white"),
breaks = c("Both", "Insulin", "Byetta", "None"),
guide = guide_legend(override.aes = list(color = c("white", "gray80", highlight),
size = c(2,2,6)))) +
scale_x_date(breaks = break.vec,
date_labels = "%b %Y") +
theme_bw() +
labs(col = "Taking:", x = "Date", y = "",
title = "",
) +
theme(legend.position = "none",
axis.text.y = element_markdown(size = axis_size),
plot.title = element_markdown(lineheight = 1.1),
legend.text = element_markdown(size = 11)
)
title <- ggdraw() + geom_richtext(
data = data.frame(x = 0.03, y = 0.5,
label = "<span style='font-size:14pt'>**Insulin and Byetta Co-Medication Study**</span><br>
<span style='font-size:11pt'>Patient ID and **co-medication rate (%)**, from January 2012 to February 2014 <br>
Comparison between the use of <span style='color:#6BB058;'>**Insulin**</span>,
<span style='color:#017182;'>**Byetta**</span> or
<span style='color:#cd5b45;'>**both**</span> medications at the same time
</span>"),
aes(x, y, label = label),
fill = NA, label.color = NA,
hjust = 0, vjust = 0.5, angle = 0,
label.padding = grid::unit(rep(0, 4), "pt"),
# color = "black",
inherit.aes = FALSE
)
plot_grid(title, plot_grid(p1,p2), nrow =2, rel_heights = c(0.2, 1))


LS0tCnRpdGxlOiAicHJvc3BlY3Rpb24gdGVzdCIKb3V0cHV0OgogIGh0bWxfbm90ZWJvb2sKLS0tCgpgYGB7cn0KbGlicmFyeSh0aWR5dmVyc2UpCmxpYnJhcnkoZ2d0ZXh0KQpsaWJyYXJ5KGNvd3Bsb3QpCmBgYAoKYGBge3J9CnBhdGllbnRzIDwtIHJlYWR4bDo6cmVhZF94bHN4KCIyLl9ieWV0dGFfaW5zdWxpbl9tdXNpY19kaWFncmFtX3Y1ICgzMCkgKDEyKS54bHN4IikKcGF0aWVudHMgJT4lIAogIGhlYWQoKQpgYGAKCmBgYHtyfQpwYXRpZW50cyA8LSBwYXRpZW50cyAlPiUgCiAgcGl2b3RfbG9uZ2VyKC1gUGF0aWVudCBJRGAsIG5hbWVzX3RvID0gImRhdGUiLCB2YWx1ZXNfdG8gPSAibWVkIikgJT4lIAogIHJlbmFtZShpZCA9IGBQYXRpZW50IElEYCkKcGF0aWVudHMKYGBgCgoKYGBge3J9CnBhdGllbnRzICU+JSAKICAjIGZpbHRlcihpZCA9PSAxKSAlPiUKICBtdXRhdGUoZGF0ZSA9IGFzLkRhdGUoYXMubnVtZXJpYyhkYXRlKSwgCiAgICAgICAgICAgICAgICAgICAgb3JpZ2luID0gJzE4OTktMTItMzAnKSkgJT4lIAogIGdyb3VwX2J5KGlkLCBkYXRlKSAlPiUgCiAgYXJyYW5nZShpZCwgZGF0ZSkgJT4lIAogIG11dGF0ZShib3VnaHRfaW5zID0gaWZlbHNlKCJJbiIgJWluJSBtZWQsIDEsIDApLAogICAgICAgICBib3VnaHRfYnkgPSBpZmVsc2UoIkJ5IiAlaW4lIG1lZCwgMSwgMCkpICU+JSAKICBmaWx0ZXIocm93X251bWJlcigpID09IDEpICU+JQogIHNlbGVjdCgtbWVkKSAlPiUKICB1bmdyb3VwKCkgJT4lIAogIGdyb3VwX2J5KGlkKSAlPiUKICBtdXRhdGUodXNlZF9pbnMgPSBpZmVsc2UoYm91Z2h0X2lucyA9PSAwICYKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAoKGxhZyhib3VnaHRfaW5zLCBkZWZhdWx0ID0gMCwgbiA9IDEpID09IDEpIHwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAobGFnKGJvdWdodF9pbnMsIGRlZmF1bHQgPSAwLCBuID0gMikgPT0gMSkgfAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIChsYWcoYm91Z2h0X2lucywgZGVmYXVsdCA9IDAsIG4gPSAzKSA9PSAxKSB8CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKGxhZyhib3VnaHRfaW5zLCBkZWZhdWx0ID0gMCwgbiA9IDQpID09IDEpIHwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAobGFnKGJvdWdodF9pbnMsIGRlZmF1bHQgPSAwLCBuID0gNSkgPT0gMSkgfAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIChsYWcoYm91Z2h0X2lucywgZGVmYXVsdCA9IDAsIG4gPSA2KSA9PSAxKSksCiAgICAgICAgICAgICAgICAgICAgICAgICAgIDEsIGJvdWdodF9pbnMpLAogICAgICAgICB1c2VkX2J5ID0gaWZlbHNlKGJvdWdodF9ieSA9PSAwICYKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAoKGxhZyhib3VnaHRfYnksIGRlZmF1bHQgPSAwLCBuID0gMSkgPT0gMSkgfAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIChsYWcoYm91Z2h0X2J5LCBkZWZhdWx0ID0gMCwgbiA9IDIpID09IDEpKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgMSwgYm91Z2h0X2J5KSwKICAgICAgICAgbl9tZWQgPSB1c2VkX2lucyArIHVzZWRfYnkpICU+JSAKICBtdXRhdGUoY29tZWQgPSBpZmVsc2UodXNlZF9pbnMgPT0gMSAmIHVzZWRfYnkgPT0gMSwgMSwgMCksCiAgICAgICAgIGNvbWVkX3JhdGUgPSByb3VuZChzdW0oY29tZWQpIC8gbigpICogMTAwLDEpKSAlPiUgCiAgc3VtbWFyaXNlKGNvbWVkX3JhdGUgPSByb3VuZChzdW0oY29tZWQpIC8gbigpICogMTAwLDEpKSAlPiUKICBhcnJhbmdlKC1jb21lZF9yYXRlKQpgYGAKCmBgYHtyfQpjb21lZCA8LSBwYXRpZW50cyAlPiUgCiAgIyBmaWx0ZXIoaWQgPT0gMSkgJT4lCiAgbXV0YXRlKGRhdGUgPSBhcy5EYXRlKGFzLm51bWVyaWMoZGF0ZSksIAogICAgICAgICAgICAgICAgICAgIG9yaWdpbiA9ICcxODk5LTEyLTMwJykpICU+JSAKICBncm91cF9ieShpZCwgZGF0ZSkgJT4lIAogIGFycmFuZ2UoaWQsIGRhdGUpICU+JSAKICBtdXRhdGUoYm91Z2h0X2lucyA9IGlmZWxzZSgiSW4iICVpbiUgbWVkLCAxLCAwKSwKICAgICAgICAgYm91Z2h0X2J5ID0gaWZlbHNlKCJCeSIgJWluJSBtZWQsIDEsIDApKSAlPiUgCiAgZmlsdGVyKHJvd19udW1iZXIoKSA9PSAxKSAlPiUKICBzZWxlY3QoLW1lZCkgJT4lCiAgdW5ncm91cCgpICU+JSAKICBncm91cF9ieShpZCkgJT4lCiAgbXV0YXRlKHVzZWRfaW5zID0gaWZlbHNlKGJvdWdodF9pbnMgPT0gMCAmCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKChsYWcoYm91Z2h0X2lucywgZGVmYXVsdCA9IDAsIG4gPSAxKSA9PSAxKSB8CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKGxhZyhib3VnaHRfaW5zLCBkZWZhdWx0ID0gMCwgbiA9IDIpID09IDEpIHwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAobGFnKGJvdWdodF9pbnMsIGRlZmF1bHQgPSAwLCBuID0gMykgPT0gMSkgfAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIChsYWcoYm91Z2h0X2lucywgZGVmYXVsdCA9IDAsIG4gPSA0KSA9PSAxKSB8CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKGxhZyhib3VnaHRfaW5zLCBkZWZhdWx0ID0gMCwgbiA9IDUpID09IDEpIHwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAobGFnKGJvdWdodF9pbnMsIGRlZmF1bHQgPSAwLCBuID0gNikgPT0gMSkpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAxLCBib3VnaHRfaW5zKSwKICAgICAgICAgdXNlZF9ieSA9IGlmZWxzZShib3VnaHRfYnkgPT0gMCAmCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKChsYWcoYm91Z2h0X2J5LCBkZWZhdWx0ID0gMCwgbiA9IDEpID09IDEpIHwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAobGFnKGJvdWdodF9ieSwgZGVmYXVsdCA9IDAsIG4gPSAyKSA9PSAxKSksCiAgICAgICAgICAgICAgICAgICAgICAgICAgIDEsIGJvdWdodF9ieSksCiAgICAgICAgIG5fbWVkID0gdXNlZF9pbnMgKyB1c2VkX2J5KSAlPiUgCiAgbXV0YXRlKGNvbWVkID0gaWZlbHNlKHVzZWRfaW5zID09IDEgJiB1c2VkX2J5ID09IDEsIDEsIDApLAogICAgICAgICBjb21lZF9yYXRlID0gcm91bmQoc3VtKGNvbWVkKSAvIG4oKSAqIDEwMCwxKSwKICAgICAgICAgbmFtZSA9IHBhc3RlMCgiIyIsaWQsICIgKCIsIGNvbWVkX3JhdGUsICIlKSIpKSAlPiUgIAogIHVuZ3JvdXAoKQpjb21lZCAKYGBgCgpgYGB7ciwgZmlnLndpZHRoPTE1LCB3YXJuaW5nPUZ9Cm15Y29sb3JzIDwtIGMoImRhcmtnb2xkZW5yb2QzIiwgImNvcmFsMyIpCmJyZWFrLnZlYyA8LSBjKHNlcShmcm9tID0gYXMuRGF0ZSgiMjAxMi0wMS0wMSIpLCB0byA9IGFzLkRhdGUoIjIwMTQtMDMtMDEiKSwKICAgICAgICAgICAgICAgICBieSA9ICI2IG1vbnRocyIpKQpnZ3Bsb3QoY29tZWQsIGFlcyh4PWRhdGUsICkpICsKICBnZW9tX2NvbChhZXMoeT1jb21lZCwgY29sID0gIkJvdGgiKSwgZmlsbCA9ICJncmF5NDAiLCBhbHBoYSA9IDAuMywgd2lkdGggPSAxNCwgc2hvdy5sZWdlbmQgPSBGKSArCiAgZ2VvbV9jb2woYWVzKHk9LWNvbWVkLCBjb2wgPSAiQm90aCIpLCBmaWxsID0gImdyYXk0MCIsIGFscGhhID0gMC4zLCB3aWR0aCA9IDE0LCBzaG93LmxlZ2VuZCA9IEYpICsKICBnZW9tX3ZsaW5lKHhpbnRlcmNlcHQgPSBhcy5udW1lcmljKGFzLkRhdGUoYygiMjAxMi0wMS0wMSIsICIyMDEzLTAxLTAxIiwgIjIwMTQtMDEtMDEiKSkpLAogICAgICAgICAgICAgY29sID0gImdyYXkyMCIsIGx3ZCA9IDAuMykgKwogIGdlb21fbGluZShhZXMoeSA9IC11c2VkX2lucywgY29sPSJJbnN1bGluIiksIHNpemUgPSAxLjIpICsKICBnZW9tX2xpbmUoYWVzKHkgPSB1c2VkX2J5LCBjb2wgPSAiQnlldHRhIiksIHNpemUgPSAxLjIpICsKICBnZW9tX3BvaW50KGFlcyh5ID0gLWJvdWdodF9pbnMgKiAyICsgMS44LCBmaWxsID0gIkluc3VsaW4iKSwgY29sID0gbXljb2xvcnNbMl0sIHNpemUgPSAwLjgpICsKICBnZW9tX3BvaW50KGFlcyh5ID0gYm91Z2h0X2J5ICogMiAtIDEuOCwgZmlsbCA9ICJCeWV0dGEiKSwgY29sID0gbXljb2xvcnNbMV0sIHNpemUgPSAwLjgsIHNob3cubGVnZW5kID0gRikgKwogIHNjYWxlX2ZpbGxfbWFudWFsKG5hbWUgPSAiQm91Z2h0OiIsCiAgICAgICAgICAgICAgICAgICAgdmFsdWVzID0gYygxLCAxKSwKICAgICAgICAgICAgICAgICAgICBicmVha3MgPSBjKCJCeWV0dGEiLCAiSW5zdWxpbiIpLAogICAgICAgICAgICAgICAgICAgIGd1aWRlID0gZ3VpZGVfbGVnZW5kKG92ZXJyaWRlLmFlcyA9IGxpc3QoY29sb3IgPSBteWNvbG9ycywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNpemUgPSAyKSkpICsKICBzY2FsZV9jb2xvcl9tYW51YWwodmFsdWVzID0gYyhteWNvbG9ycywgYWxwaGEoIndoaXRlIiwgMCkpLAogICAgICAgICAgICAgICAgICAgICBicmVha3MgPSBjKCJCeWV0dGEiLCAiSW5zdWxpbiIsICJCb3RoIiksCiAgICAgICAgICAgICAgICAgICAgIGd1aWRlID0gZ3VpZGVfbGVnZW5kKG92ZXJyaWRlLmFlcyA9IGxpc3QoY29sb3IgPSBjKG15Y29sb3JzLCAiZ3JheTgwIiksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc2l6ZSA9IGMoMiwyLDYpKSkpICsKICBzY2FsZV95X2NvbnRpbnVvdXMoYnJlYWtzID0gYygtMSwwLDEpLCBsYWJlbHMgPSBjKCJJbnN1bGluIiwgIk5vbmUiLCAiQnlldHRhIiksIGxpbWl0cyA9IGMoLTEsMSkpICsKICAjIHNjYWxlX3hfZGF0ZShkYXRlX2xhYmVscyA9ICIlYiAlWSIsIGRhdGVfYnJlYWtzID0gIjYgbW9udGhzIiwKICAjICAgICAgICAgICAgICBtaW5vcl9icmVha3MgPSAiMSBtb250aCIsCiAgIyAgICAgICAgICAgICAgZXhwYW5kID0gYygwLDApLAogICMgICAgICAgICAgICAgIGxpbWl0cyA9IGMobWluPW1pbihkYXRlKSwgbWF4ID0gbWF4KGRhdGUpKSwKICAjICAgICAgICAgICAgICApICsKICBzY2FsZV94X2RhdGUoYnJlYWtzID0gYnJlYWsudmVjLAogICAgICAgICAgICAgICBkYXRlX2xhYmVscyA9ICIlYiAlWSIpICsKICBmYWNldF93cmFwKGlkIH4uLCBsYWJlbGxlciA9IGFzX2xhYmVsbGVyKHNldE5hbWVzKGNvbWVkJG5hbWUsIGNvbWVkJGlkKSkpICsKICBsYWJzKGNvbCA9ICJUYWtpbmc6IiwgeCA9ICJEYXRlIiwgeSA9ICJNZWRpY2F0aW9uIiwKICAgICAgIHRpdGxlID0gIkluc3VsaW4gYW5kIEJ5ZXR0YSBDby1NZWRpY2F0aW9uIFN0dWR5IiwgCiAgICAgICBzdWJ0aXRsZSA9ICJQYXRpZW50IElEIGFuZCBjby1tZWRpY2F0aW9uIHJhdGUgKCUpLCBmcm9tIEphbnVhcnkgMjAxMiB0byBGZWJydWFyeSAyMDE0IikgKwogIHRoZW1lX2J3KCkgKwogIHRoZW1lKGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGFuZ2xlID0gOTAsIGhqdXN0ID0gMSwgdmp1c3QgPSAwLjUpLAogICAgICAgIHBhbmVsLmdyaWQubWlub3IueSA9IGVsZW1lbnRfYmxhbmsoKSwKICAgICAgICBzdHJpcC5iYWNrZ3JvdW5kID0gZWxlbWVudF9yZWN0KGZpbGwgPSAiZ3JheTk4IikpCmBgYAoKYGBge3J9CmNvbWVkICU+JSAKICBtdXRhdGUoaWQgPSBmY3RfcmVvcmRlcihhcy5mYWN0b3IoaWQpLCBjb21lZF9yYXRlKSkgJT4lIAogIHB1bGwoaWQpCmBgYAoKCmBgYHtyLCBmaWcud2lkdGg9MTUsIHdhcm5pbmc9Rn0KbXljb2xvcnMgPC0gYygiZGFya2dvbGRlbnJvZDMiLCAiY29yYWwzIikKYnJlYWsudmVjIDwtIGMoc2VxKGZyb20gPSBhcy5EYXRlKCIyMDEyLTAxLTAxIiksIHRvID0gYXMuRGF0ZSgiMjAxNC0wMy0wMSIpLAogICAgICAgICAgICAgICAgIGJ5ID0gIjYgbW9udGhzIikpCgpnZ3Bsb3QoY29tZWQgJT4lIG11dGF0ZShpZCA9IGZjdF9yZW9yZGVyKGFzLmZhY3RvcihpZCksIC1jb21lZF9yYXRlKSksIGFlcyh4PWRhdGUsICkpICsKICBnZW9tX2NvbChhZXMoeT1jb21lZCwgY29sID0gIkJvdGgiKSwgZmlsbCA9ICJncmF5NDAiLCBhbHBoYSA9IDAuMywgd2lkdGggPSAxNCwgc2hvdy5sZWdlbmQgPSBGKSArCiAgZ2VvbV9jb2woYWVzKHk9LWNvbWVkLCBjb2wgPSAiQm90aCIpLCBmaWxsID0gImdyYXk0MCIsIGFscGhhID0gMC4zLCB3aWR0aCA9IDE0LCBzaG93LmxlZ2VuZCA9IEYpICsKICBnZW9tX3ZsaW5lKHhpbnRlcmNlcHQgPSBhcy5udW1lcmljKGFzLkRhdGUoYygiMjAxMi0wMS0wMSIsICIyMDEzLTAxLTAxIiwgIjIwMTQtMDEtMDEiKSkpLAogICAgICAgICAgICAgY29sID0gImdyYXkyMCIsIGx3ZCA9IDAuMykgKwogIGdlb21fbGluZShhZXMoeSA9IC11c2VkX2lucywgY29sPSJJbnN1bGluIiksIHNpemUgPSAxLjIpICsKICBnZW9tX2xpbmUoYWVzKHkgPSB1c2VkX2J5LCBjb2wgPSAiQnlldHRhIiksIHNpemUgPSAxLjIpICsKICBnZW9tX3BvaW50KGFlcyh5ID0gLWJvdWdodF9pbnMgKiAyICsgMS44LCBmaWxsID0gIkluc3VsaW4iKSwgY29sID0gbXljb2xvcnNbMl0sIHNpemUgPSAwLjgpICsKICBnZW9tX3BvaW50KGFlcyh5ID0gYm91Z2h0X2J5ICogMiAtIDEuOCwgZmlsbCA9ICJCeWV0dGEiKSwgY29sID0gbXljb2xvcnNbMV0sIHNpemUgPSAwLjgsIHNob3cubGVnZW5kID0gRikgKwogIHNjYWxlX2ZpbGxfbWFudWFsKG5hbWUgPSAiQm91Z2h0OiIsCiAgICAgICAgICAgICAgICAgICAgdmFsdWVzID0gYygxLCAxKSwKICAgICAgICAgICAgICAgICAgICBicmVha3MgPSBjKCJCeWV0dGEiLCAiSW5zdWxpbiIpLAogICAgICAgICAgICAgICAgICAgIGd1aWRlID0gZ3VpZGVfbGVnZW5kKG92ZXJyaWRlLmFlcyA9IGxpc3QoY29sb3IgPSBteWNvbG9ycywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNpemUgPSAyKSkpICsKICBzY2FsZV9jb2xvcl9tYW51YWwodmFsdWVzID0gYyhteWNvbG9ycywgYWxwaGEoIndoaXRlIiwgMCkpLAogICAgICAgICAgICAgICAgICAgICBicmVha3MgPSBjKCJCeWV0dGEiLCAiSW5zdWxpbiIsICJCb3RoIiksCiAgICAgICAgICAgICAgICAgICAgIGd1aWRlID0gZ3VpZGVfbGVnZW5kKG92ZXJyaWRlLmFlcyA9IGxpc3QoY29sb3IgPSBjKG15Y29sb3JzLCAiZ3JheTgwIiksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc2l6ZSA9IGMoMiwyLDYpKSkpICsKICBzY2FsZV95X2NvbnRpbnVvdXMoYnJlYWtzID0gYygtMSwwLDEpLCBsYWJlbHMgPSBjKCJJbnN1bGluIiwgIk5vbmUiLCAiQnlldHRhIiksIGxpbWl0cyA9IGMoLTEsMSkpICsKICBzY2FsZV94X2RhdGUoYnJlYWtzID0gYnJlYWsudmVjLAogICAgICAgICAgICAgICBkYXRlX2xhYmVscyA9ICIlYiAlWSIpICsKICBmYWNldF93cmFwKGlkIH4uLCBsYWJlbGxlciA9IGFzX2xhYmVsbGVyKHNldE5hbWVzKGNvbWVkJG5hbWUsIGNvbWVkJGlkKSkpICsKICBsYWJzKGNvbCA9ICJUYWtpbmc6IiwgeCA9ICJEYXRlIiwgeSA9ICJNZWRpY2F0aW9uIiwKICAgICAgIHRpdGxlID0gIkluc3VsaW4gYW5kIEJ5ZXR0YSBDby1NZWRpY2F0aW9uIFN0dWR5IiwgCiAgICAgICBzdWJ0aXRsZSA9ICJQYXRpZW50IElEIGFuZCBjby1tZWRpY2F0aW9uIHJhdGUgKCUpLCBmcm9tIEphbnVhcnkgMjAxMiB0byBGZWJydWFyeSAyMDE0IikgKwogIHRoZW1lX2J3KCkgKwogIHRoZW1lKGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGFuZ2xlID0gOTAsIGhqdXN0ID0gMSwgdmp1c3QgPSAwLjUpLAogICAgICAgIHBhbmVsLmdyaWQubWlub3IueSA9IGVsZW1lbnRfYmxhbmsoKSwKICAgICAgICBzdHJpcC5iYWNrZ3JvdW5kID0gZWxlbWVudF9yZWN0KGZpbGwgPSAiZ3JheTk4IikpCmBgYAoKYGBge3IsIGZpZy53aWR0aD03LCB3YXJuaW5nPUZ9Cm15Y29sb3JzIDwtIGMoImRhcmtnb2xkZW5yb2QzIiwgImNvcmFsMyIpCm15Y29sb3JzIDwtIGMoIiM5MEVGNzciLCAiIzAxNzE4MiIpICM5YWVlODQsICMwNzNBNTIKaGlnaGxpZ2h0IDwtICJjb3JhbDMiICMiI0ZDMUI1MSIKYnJlYWsudmVjIDwtIGMoc2VxKGZyb20gPSBhcy5EYXRlKCIyMDEyLTAxLTAxIiksIHRvID0gYXMuRGF0ZSgiMjAxNC0wMy0wMSIpLAogICAgICAgICAgICAgICAgIGJ5ID0gIjYgbW9udGhzIikpCgpwZGF0YSA8LSBjb21lZCAlPiUgZmlsdGVyKGlkIDwgNTAwKSAlPiUgbXV0YXRlKGlkID0gZmN0X3Jlb3JkZXIoYXMuZmFjdG9yKGlkKSwgLWNvbWVkX3JhdGUpKQpnZ3Bsb3QocGRhdGEsIGFlcyh4PWRhdGUsICkpICsKICBnZW9tX2NvbChkYXRhID0gcGRhdGEgJT4lIGZpbHRlcihuX21lZCA8PSAxKSwKICAgICAgICAgICBhZXMoeT1uX21lZCwgY29sID0gIkJvdGgiKSwgZmlsbCA9ICJncmF5NDAiLCBhbHBoYSA9IDAuNSwgd2lkdGggPSAxNCwgc2hvdy5sZWdlbmQgPSBGKSArCiAgIyBnZW9tX2xpbmUoYWVzKHk9bl9tZWQpLCBjb2w9ImJsYWNrIiwgc2hvdy5sZWdlbmQgPSBGKSArCiAgZ2VvbV9jb2woZGF0YSA9IHBkYXRhICU+JSBmaWx0ZXIobl9tZWQgPiAxKSwKICAgICAgICAgICBhZXMoeT1uX21lZCwgY29sID0gIkJvdGgiKSwgZmlsbCA9IGhpZ2hsaWdodCwgYWxwaGEgPSAwLjYsIHdpZHRoID0gMTQsIHNob3cubGVnZW5kID0gRikgKwogIGdlb21fdmxpbmUoeGludGVyY2VwdCA9IGFzLm51bWVyaWMoYXMuRGF0ZShjKCIyMDEyLTAxLTAxIiwgIjIwMTMtMDEtMDEiLCAiMjAxNC0wMS0wMSIpKSksCiAgICAgICAgICAgICBjb2wgPSAiZ3JheTIwIiwgbHdkID0gMC4zKSArCiAgIyBnZW9tX2xpbmUoYWVzKHkgPSAtdXNlZF9pbnMsIGNvbD0iSW5zdWxpbiIpLCBzaXplID0gMS4yKSArCiAgIyBnZW9tX2xpbmUoYWVzKHkgPSB1c2VkX2J5LCBjb2wgPSAiQnlldHRhIiksIHNpemUgPSAxLjIpICsKICBnZW9tX3BvaW50KGRhdGEgPSBwZGF0YSAlPiUgZmlsdGVyKHVzZWRfaW5zID09IDEsIG5fbWVkID09IDEpLAogICAgICAgICAgICAgYWVzKHkgPSAwLjEsIGZpbGwgPSAiSW5zdWxpbiIpLCBjb2wgPSBteWNvbG9yc1sxXSwgc2l6ZSA9IDAuNikgKwogIGdlb21fcG9pbnQoZGF0YSA9IHBkYXRhICU+JSBmaWx0ZXIodXNlZF9ieSA9PSAxLCBuX21lZCA9PSAxKSwKICAgICAgICAgICAgIGFlcyh5ID0gMC4xLCBmaWxsID0gIkJ5ZXR0YSIpLCBjb2wgPSBteWNvbG9yc1syXSwgc2l6ZSA9IDAuNikgKwogIGdlb21fcG9pbnQoYWVzKHkgPSAtMSwgZmlsbCA9ICJCb3RoIiksKSArCiAgIyBnZW9tX3BvaW50KGFlcyh5ID0gYm91Z2h0X2J5ICogMiAtIDEuOCwgZmlsbCA9ICJCeWV0dGEiKSwgY29sID0gbXljb2xvcnNbMV0sIHNpemUgPSAwLjgsIHNob3cubGVnZW5kID0gRikgKwogIHNjYWxlX2ZpbGxfbWFudWFsKG5hbWUgPSAiTWVkaWNhdGlvbjoiLAogICAgICAgICAgICAgICAgICAgIHZhbHVlcyA9IGMoMSwgMSwgMSksCiAgICAgICAgICAgICAgICAgICAgYnJlYWtzID0gYygiSW5zdWxpbiIsICJCeWV0dGEiLCAiQm90aCIpLAogICAgICAgICAgICAgICAgICAgIGd1aWRlID0gZ3VpZGVfbGVnZW5kKG92ZXJyaWRlLmFlcyA9IGxpc3QoY29sb3IgPSBjKG15Y29sb3JzLCBoaWdobGlnaHQpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc2hhcGUgPSBjKDE2LDE2LDE1KSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGFscGhhID0gYygxLDEsMC40KSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNpemUgPSBjKDIsMiw2KSkpKSArCiAgc2NhbGVfY29sb3JfbWFudWFsKHZhbHVlcyA9IGMobXljb2xvcnMsIGFscGhhKCJ3aGl0ZSIsIDApKSwKICAgICAgICAgICAgICAgICAgICAgYnJlYWtzID0gYygiQnlldHRhIiwgIkluc3VsaW4iLCAiQm90aCIpLAogICAgICAgICAgICAgICAgICAgICBndWlkZSA9IGd1aWRlX2xlZ2VuZChvdmVycmlkZS5hZXMgPSBsaXN0KGNvbG9yID0gYyhteWNvbG9ycywgImdyYXk4MCIpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNpemUgPSBjKDIsMiw2KSkpKSArCiAgc2NhbGVfeV9jb250aW51b3VzKGJyZWFrcyA9IGMoMCwxLDIpLAogICAgICAgICAgICAgICAgICAgICBsYWJlbHMgPSBjKCIwIiwgIjEiLCAiMiIpLAogICAgICAgICAgICAgICAgICAgICBsaW1pdHMgPSBjKDAsIDIpKSArCiAgc2NhbGVfeF9kYXRlKGJyZWFrcyA9IGJyZWFrLnZlYywKICAgICAgICAgICAgICAgZGF0ZV9sYWJlbHMgPSAiJWIgJVkiKSArCiAgZmFjZXRfd3JhcChpZCB+LiwgbGFiZWxsZXIgPSBhc19sYWJlbGxlcihzZXROYW1lcyhjb21lZCRuYW1lLCBjb21lZCRpZCkpKSArCiAgbGFicyhjb2wgPSAiVGFraW5nOiIsIHggPSAiRGF0ZSIsIHkgPSAiIyBUYWtlbiBNZWRpY2F0aW9ucyIsCiAgICAgICB0aXRsZSA9ICJJbnN1bGluIGFuZCBCeWV0dGEgQ28tTWVkaWNhdGlvbiBTdHVkeSIsIAogICAgICAgc3VidGl0bGUgPSAiUGF0aWVudCBJRCBhbmQgY28tbWVkaWNhdGlvbiByYXRlICglKSwgZnJvbSBKYW51YXJ5IDIwMTIgdG8gRmVicnVhcnkgMjAxNCIpICsKICB0aGVtZV9idygpICsKICB0aGVtZShheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChhbmdsZSA9IDkwLCBoanVzdCA9IDEsIHZqdXN0ID0gMC41KSwKICAgICAgICBheGlzLnRleHQueSA9IGVsZW1lbnRfYmxhbmsoKSwKICAgICAgICBheGlzLnRpY2tzLnkgPSBlbGVtZW50X2JsYW5rKCksCiAgICAgICAgcGFuZWwuZ3JpZC5taW5vci55ID0gZWxlbWVudF9ibGFuaygpLAogICAgICAgIHN0cmlwLmJhY2tncm91bmQgPSBlbGVtZW50X3JlY3QoZmlsbCA9ICJncmF5OTgiKSkKYGBgCgpgYGB7ciwgZmlnLndpZHRoPTUsIGZpZy5oZWlnaHQ9Mn0KcGRhdGEgPC0gY29tZWQgJT4lIGZpbHRlcihpZCA8IDUwMCkgJT4lIG11dGF0ZShpZCA9IGZjdF9yZW9yZGVyKGFzLmZhY3RvcihpZCksIGNvbWVkX3JhdGUpKSAlPiUgCiAgbXV0YXRlKG1lZCA9IGNhc2Vfd2hlbigKICAgIG5fbWVkID09IDIgfiAiQm90aCIsIAogICAgbl9tZWQgPT0gMSAmIHVzZWRfaW5zID09IDEgfiAiSW5zdWxpbiIsCiAgICBuX21lZCA9PSAxICYgdXNlZF9ieSA9PSAxIH4gIkJ5ZXR0YSIsCiAgICBUUlVFIH4gIk5vbmUiCiAgKSwKICBhbHBoYSA9IGlmZWxzZShtZWQgPT0gIk5vbmUiLCAwLCAxKSwKICBuYW1lID0gcGFzdGUwKCIjIixpZCwgIiAqKigiLCBjb21lZF9yYXRlLCAiJSkqKiIpKQpheGlzX3NpemUgPC0gNS41CnAxIDwtIGdncGxvdChwZGF0YSAlPiUgZmlsdGVyKGFzLm51bWVyaWMoaWQpID4gMzQpLCBhZXMoeD1kYXRlLCB5PWlkKSkgKwogIGdlb21fdGlsZShhZXMoZmlsbCA9IGZhY3RvcihtZWQpLCBhbHBoYSA9IGFscGhhKSwgc2l6ZSA9IDEpICsKICAjIGdlb21fcG9pbnQoYWVzKGNvbCA9IGZhY3RvcihtZWQpLCBhbHBoYSA9IGFscGhhKSwgc2hhcGUgPSAxNSwgc2l6ZSA9IDUpICsKICAjIGdlb21fcG9pbnQoZGF0YSA9IHBkYXRhICU+JSBmaWx0ZXIodXNlZF9pbnMgPT0gMSwgbl9tZWQgPT0gMSksCiAgIyAgICAgICAgICAgIGFlcyhmaWxsID0gIkluc3VsaW4iKSwgY29sID0gbXljb2xvcnNbMV0sIHNpemUgPSAwLjYpICsKICAjIGdlb21fcG9pbnQoZGF0YSA9IHBkYXRhICU+JSBmaWx0ZXIodXNlZF9ieSA9PSAxLCBuX21lZCA9PSAxKSwKICAjICAgICAgICAgICAgYWVzKGZpbGwgPSAiQnlldHRhIiksIGNvbCA9IG15Y29sb3JzWzJdLCBzaXplID0gMC42KSArCiAgc2NhbGVfeV9kaXNjcmV0ZShicmVha3MgPSBwZGF0YSRpZCwKICAgICAgICAgICAgICAgICAgIGxhYmVscyA9IHBkYXRhJG5hbWUpICsKICBzY2FsZV9maWxsX21hbnVhbCh2YWx1ZXMgPSBjKGhpZ2hsaWdodCwgbXljb2xvcnMsICJ3aGl0ZSIpLAogICAgICAgICAgICAgICAgICAgICBicmVha3MgPSBjKCJCb3RoIiwgIkluc3VsaW4iLCAiQnlldHRhIiwgIk5vbmUiKSwKICAgICAgICAgICAgICAgICAgICAgZ3VpZGUgPSBndWlkZV9sZWdlbmQob3ZlcnJpZGUuYWVzID0gbGlzdChjb2xvciA9IGMoIndoaXRlIiwgImdyYXk4MCIsIGhpZ2hsaWdodCksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc2l6ZSA9IGMoMiwyLDYpKSkpICsKICBzY2FsZV94X2RhdGUoYnJlYWtzID0gYnJlYWsudmVjLAogICAgICAgICAgICAgICBkYXRlX2xhYmVscyA9ICIlYiAlWSIpICsKICB0aGVtZV9idygpICsKICBsYWJzKGNvbCA9ICJUYWtpbmc6IiwgeCA9ICJEYXRlIiwgeSA9ICJQYXRpZW50IElEIiwKICApICsKICB0aGVtZShsZWdlbmQucG9zaXRpb24gPSAibm9uZSIsCiAgICAgICAgYXhpcy50ZXh0LnkgPSBlbGVtZW50X21hcmtkb3duKHNpemU9YXhpc19zaXplKSwKICAgICAgICBwbG90LnRpdGxlID0gZWxlbWVudF9tYXJrZG93bihsaW5laGVpZ2h0ID0gMS4xKSwKICAgICAgICBsZWdlbmQudGV4dCA9IGVsZW1lbnRfbWFya2Rvd24oc2l6ZSA9IDExKQogICAgICAgICkKcDIgPC0gZ2dwbG90KHBkYXRhICU+JSBmaWx0ZXIoYXMubnVtZXJpYyhpZCkgPD0gMzQpLCBhZXMoeD1kYXRlLCB5PWlkKSkgKwogIGdlb21fdGlsZShhZXMoZmlsbCA9IGZhY3RvcihtZWQpLCBhbHBoYSA9IGFscGhhKSwgc2l6ZSA9IDEpICsKICBzY2FsZV95X2Rpc2NyZXRlKGJyZWFrcyA9IHBkYXRhJGlkLAogICAgICAgICAgICAgICAgICAgbGFiZWxzID0gcGRhdGEkbmFtZSkgKwogIHNjYWxlX2ZpbGxfbWFudWFsKHZhbHVlcyA9IGMoaGlnaGxpZ2h0LCBteWNvbG9ycywgIndoaXRlIiksCiAgICAgICAgICAgICAgICAgICAgIGJyZWFrcyA9IGMoIkJvdGgiLCAiSW5zdWxpbiIsICJCeWV0dGEiLCAiTm9uZSIpLAogICAgICAgICAgICAgICAgICAgICBndWlkZSA9IGd1aWRlX2xlZ2VuZChvdmVycmlkZS5hZXMgPSBsaXN0KGNvbG9yID0gYygid2hpdGUiLCAiZ3JheTgwIiwgaGlnaGxpZ2h0KSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzaXplID0gYygyLDIsNikpKSkgKwogIHNjYWxlX3hfZGF0ZShicmVha3MgPSBicmVhay52ZWMsCiAgICAgICAgICAgICAgIGRhdGVfbGFiZWxzID0gIiViICVZIikgKwogIHRoZW1lX2J3KCkgKwogIGxhYnMoY29sID0gIlRha2luZzoiLCB4ID0gIkRhdGUiLCB5ID0gIiIsCiAgICAgICB0aXRsZSA9ICIiLAogICkgKwogIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbiA9ICJub25lIiwKICAgICAgICBheGlzLnRleHQueSA9IGVsZW1lbnRfbWFya2Rvd24oc2l6ZSA9IGF4aXNfc2l6ZSksCiAgICAgICAgcGxvdC50aXRsZSA9IGVsZW1lbnRfbWFya2Rvd24obGluZWhlaWdodCA9IDEuMSksCiAgICAgICAgbGVnZW5kLnRleHQgPSBlbGVtZW50X21hcmtkb3duKHNpemUgPSAxMSkKICAgICAgICApCnRpdGxlIDwtIGdnZHJhdygpICsgZ2VvbV9yaWNodGV4dCgKICAgIGRhdGEgPSBkYXRhLmZyYW1lKHggPSAwLjAzLCB5ID0gMC41LCAKICAgICAgICAgICAgICAgICAgICAgIGxhYmVsID0gIjxzcGFuIHN0eWxlPSdmb250LXNpemU6MTRwdCc+KipJbnN1bGluIGFuZCBCeWV0dGEgQ28tTWVkaWNhdGlvbiBTdHVkeSoqPC9zcGFuPjxicj4KICAgIDxzcGFuIHN0eWxlPSdmb250LXNpemU6MTFwdCc+UGF0aWVudCBJRCBhbmQgKipjby1tZWRpY2F0aW9uIHJhdGUgKCUpKiosIGZyb20gSmFudWFyeSAyMDEyIHRvIEZlYnJ1YXJ5IDIwMTQgPGJyPiAKICAgIENvbXBhcmlzb24gYmV0d2VlbiB0aGUgdXNlIG9mIDxzcGFuIHN0eWxlPSdjb2xvcjojNkJCMDU4Oyc+KipJbnN1bGluKio8L3NwYW4+LCAKICAgIDxzcGFuIHN0eWxlPSdjb2xvcjojMDE3MTgyOyc+KipCeWV0dGEqKjwvc3Bhbj4gb3IKICAgIDxzcGFuIHN0eWxlPSdjb2xvcjojY2Q1YjQ1Oyc+Kipib3RoKio8L3NwYW4+IG1lZGljYXRpb25zIGF0IHRoZSBzYW1lIHRpbWUKICAgIDwvc3Bhbj4iKSwKICAgIGFlcyh4LCB5LCBsYWJlbCA9IGxhYmVsKSwKICAgIGZpbGwgPSBOQSwgbGFiZWwuY29sb3IgPSBOQSwKICAgIGhqdXN0ID0gMCwgdmp1c3QgPSAwLjUsIGFuZ2xlID0gMCwKICAgIGxhYmVsLnBhZGRpbmcgPSBncmlkOjp1bml0KHJlcCgwLCA0KSwgInB0IiksCiAgICAjIGNvbG9yID0gImJsYWNrIiwKICAgIGluaGVyaXQuYWVzID0gRkFMU0UKICApCnBsb3RfZ3JpZCh0aXRsZSwgcGxvdF9ncmlkKHAxLHAyKSwgbnJvdyA9MiwgcmVsX2hlaWdodHMgPSBjKDAuMiwgMSkpCmBgYAoKYGBge3IsIHdhcm5pbmc9RkFMU0UsIGZpZy53aWR0aD00fQpjb21lZF9kZWxheSA8LSBjb21lZCAlPiUgCiAgIyBmaWx0ZXIoaWQgPT0gNjUpICU+JQogIHNlbGVjdChpZCwgZGF0ZSwgYm91Z2h0X2lucywgYm91Z2h0X2J5KSAlPiUgCiAgZ3JvdXBfYnkoaWQsIGJvdWdodF9pbnMpICU+JSAKICBhcnJhbmdlKGRhdGUpICU+JSAKICBtdXRhdGUoZGVsYXlfaW5zID0gaWZlbHNlKGJvdWdodF9pbnMgPT0gMSwgYXMubnVtZXJpYyhkYXRlIC0gbGFnKGRhdGUpKSwgTkEpKSAlPiUgCiAgdW5ncm91cCgpICU+JSAKICBncm91cF9ieShpZCwgYm91Z2h0X2J5KSAlPiUgCiAgbXV0YXRlKGRlbGF5X2J5ID0gaWZlbHNlKGJvdWdodF9ieSA9PSAxLCBhcy5udW1lcmljKGRhdGUgLSBsYWcoZGF0ZSkpLCBOQSkpICU+JSAKICB1bmdyb3VwKCkgJT4lIAogIGdyb3VwX2J5KGlkKSAlPiUgCiAgc3VtbWFyaXNlKGF2Z19kZWxheV9pbnMgPSByb3VuZChzdW0oZGVsYXlfaW5zLCBuYS5ybT1UKSAvIChzdW0oYm91Z2h0X2lucyktMSksMSksCiAgICAgICAgICAgIGF2Z19kZWxheV9ieSA9IHJvdW5kKHN1bShkZWxheV9ieSwgbmEucm09VCkgLyAoc3VtKGJvdWdodF9ieSktMSksMSkpCgpjb21lZF9kZWxheSAlPiUgCiAgbXV0YXRlKGlkID0gZmN0X3Jlb3JkZXIoYXMuZmFjdG9yKGlkKSwgLWF2Z19kZWxheV9pbnMpKSAlPiUgCiAgYXJyYW5nZSgtYXZnX2RlbGF5X2lucykgJT4lIAogIGdncGxvdChhZXMoeD1pZCkpICsKICB0aGVtZV9idygpICsKICBnZW9tX2NvbChhZXMoeT1hdmdfZGVsYXlfaW5zLCBmaWxsPSJJbnN1bGluIiksIGFscGhhID0gMC44KSArCiAgZ2VvbV9jb2woYWVzKHk9YXZnX2RlbGF5X2J5LCBmaWxsPSJCeWV0dGEiKSwgYWxwaGEgPSAwLjUpICsKICBnZW9tX2hsaW5lKHlpbnRlcmNlcHQgPSA5MCwgY29sID0gIiM2QkIwNTgiLCBzaXplID0gMS41KSArCiAgZ2VvbV9obGluZSh5aW50ZXJjZXB0ID0gMzAsIGNvbCA9IG15Y29sb3JzWzJdLCBzaXplID0gMS41KSArCiAgc2NhbGVfeV9jb250aW51b3VzKGJyZWFrcyA9IHNjYWxlczo6cHJldHR5X2JyZWFrcyhuPTgpKSArCiAgZ2VvbV90ZXh0KGFlcyh4ID0gNjgsIHkgPSAxMDApLCBsYWJlbCA9ICJUaGVvcmV0aWNhbCBkZWxheSBmb3IgSW5zdWxpbiAoZGF5cykiLCBoanVzdCA9IDEsIHNpemUgPTMsIGNvbCA9ICIjNkJCMDU4IiApICsKICBnZW9tX3RleHQoYWVzKHggPSA2OCwgeSA9IDQwKSwgbGFiZWwgPSAiYW5kIEJ5ZXR0YSIsIGhqdXN0ID0gMSwgc2l6ZSA9MywgY29sID0gbXljb2xvcnNbMl0gKSArCiAgc2NhbGVfZmlsbF9tYW51YWwodmFsdWVzID0gbXljb2xvcnMsCiAgICAgICAgICAgICAgICAgICAgYnJlYWtzID0gYygiSW5zdWxpbiIsICJCeWV0dGEiKSkgKwogIGxhYnMoeCA9ICJQYXRpZW50IElEIiwgeT0iQXZlcmFnZSBidXlpbmcgZGVsYXkgKGRheXMpIikgKwogIHRoZW1lKGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGFuZ2xlID0gNDUsIGhqdXN0ID0gMSwgc2l6ZSA9IDcpLAogICAgICAgIHBhbmVsLmdyaWQubWlub3IueSA9IGVsZW1lbnRfYmxhbmsoKSwKICAgICAgICBsZWdlbmQucG9zaXRpb24gPSAibm9uZSIsCiAgICAgICAgcGFuZWwuZ3JpZC5tYWpvci54ID0gZWxlbWVudF9ibGFuaygpKQpgYGAKCg==